home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / share / system-config-printer / PhysicalDevice.py < prev    next >
Text File  |  2009-10-19  |  9KB  |  243 lines

  1. #!/usr/bin/env python
  2.  
  3. ## Copyright (C) 2008, 2009 Tim Waugh <twaugh@redhat.com>
  4. ## Copyright (C) 2008, 2009 Red Hat, Inc.
  5.  
  6. ## This program is free software; you can redistribute it and/or modify
  7. ## it under the terms of the GNU General Public License as published by
  8. ## the Free Software Foundation; either version 2 of the License, or
  9. ## (at your option) any later version.
  10.  
  11. ## This program is distributed in the hope that it will be useful,
  12. ## but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. ## GNU General Public License for more details.
  15.  
  16. ## You should have received a copy of the GNU General Public License
  17. ## along with this program; if not, write to the Free Software
  18. ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  
  20. from gettext import gettext as _
  21. import cupshelpers
  22. import urllib
  23. import re, subprocess
  24.  
  25. class PhysicalDevice:
  26.     def __init__(self, device):
  27.         self.devices = None
  28.         self._network_host = None
  29.         self.add_device (device)
  30.         self._user_data = {}
  31.  
  32.     def _canonical_id (self, device):
  33.         if device.id_dict:
  34.             mfg = device.id_dict.get ('MFG', '')
  35.             mdl = device.id_dict.get ('MDL', '')
  36.  
  37.         if mfg == '' or mdl.lower ().startswith (mfg.lower ()):
  38.             make_and_model = mdl
  39.         else:
  40.             make_and_model = "%s %s" % (mfg, mdl)
  41.  
  42.         return cupshelpers.ppds.ppdMakeModelSplit (make_and_model)
  43.  
  44.     def _get_host_from_uri (self, uri):
  45.         def expandpercent (searchres):
  46.             expr = searchres.group(0)
  47.             return chr(int(expr[1:], 16))
  48.         (scheme, rest) = urllib.splittype (uri)
  49.         if scheme == 'hp' or scheme == 'hpfax':
  50.             if rest.startswith ("/net/"):
  51.                 (rest, ipparam) = urllib.splitquery (rest[5:])
  52.                 if ipparam != None and ipparam.startswith("ip="):
  53.                     hostport = ipparam[3:]
  54.                 else:
  55.                     return None
  56.         elif scheme == 'dnssd' or scheme == 'mdns':
  57.             (hostport, rest) = urllib.splithost (rest)
  58.             p = hostport.find(".")
  59.             if (p != -1):
  60.                hostport = hostport[:p]
  61.             if hostport == '':
  62.                 return None
  63.             hostport = hostport.encode('utf-8')
  64.             hostport = re.sub("%(?i)[\dabcdef]{2}", expandpercent,
  65.                               hostport);
  66.             if not uri.endswith("/cups"):
  67.                 for mode in ("-c", "-t"):
  68.                     cmd = ("avahi-browse -a -r %s -k 2>/dev/null | " + \
  69.                            "grep -A4 '^=' | grep -F -A4 '%s' | " + \
  70.                            "grep address | head -1 | " + \
  71.                            "cut -d '[' -f 2 | cut -d ']' -f 1") % \
  72.                            (mode, hostport)
  73.                     try:
  74.                         p = subprocess.Popen (cmd, shell=True,
  75.                                               stdin=file("/dev/null"),
  76.                                               stdout=subprocess.PIPE,
  77.                                               stderr=subprocess.PIPE)
  78.                         (stdout, stderr) = p.communicate ()
  79.                         if p.returncode == 0:
  80.                             ip = stdout.strip ()
  81.                             if ip != "":
  82.                                 hostport = ip
  83.                                 break
  84.                     except:
  85.                         # Problem executing command.
  86.                         pass
  87.         else:
  88.             (hostport, rest) = urllib.splithost (rest)
  89.             if hostport == None:
  90.                 return None
  91.  
  92.         (host, port) = urllib.splitport (hostport)
  93.         return host
  94.  
  95.     def add_device (self, device):
  96.         if self._network_host:
  97.             host = self._get_host_from_uri (device.uri)
  98.             if host != self._network_host:
  99.                 raise ValueError
  100.         else:
  101.             (mfg, mdl) = self._canonical_id (device)
  102.             if self.devices == None:
  103.                 self.mfg = mfg
  104.                 self.mdl = mdl
  105.                 self.mfg_lower = mfg.lower ()
  106.                 self.mdl_lower = mdl.lower ()
  107.                 self.sn = device.id_dict.get ('SN', '')
  108.                 self.devices = []
  109.             else:
  110.                 def nicest (a, b):
  111.                     def count_lower (s):
  112.                         l = s.lower ()
  113.                         n = 0
  114.                         for i in xrange (len (s)):
  115.                             if l[i] != s[i]:
  116.                                 n += 1
  117.                         return n
  118.                     if count_lower (b) < count_lower (a):
  119.                         return b
  120.                     return a
  121.  
  122.                 self.mfg = nicest (self.mfg, mfg)
  123.                 self.mdl = nicest (self.mdl, mdl)
  124.  
  125.                 sn = device.id_dict.get ('SN', '')
  126.                 if sn != '' and self.sn != '' and sn != self.sn:
  127.                     raise ValueError
  128.  
  129.         for d in self.devices:
  130.             if d.uri == device.uri:
  131.                 return
  132.  
  133.         self.devices.append (device)
  134.         self.devices.sort ()
  135.  
  136.         if not self._network_host and device.device_class == "network":
  137.             # We just added a network device.
  138.             self._network_host = self._get_host_from_uri (device.uri)
  139.  
  140.     def get_devices (self):
  141.         return self.devices
  142.  
  143.     def get_info (self):
  144.         # If the manufacturer/model is not known, or useless (in the
  145.         # case of the hpfax backend or a dnssd URI pointing to a remote
  146.         # CUPS queue), show the device-info field
  147.         # instead.
  148.         if self.mfg == '' or (self.mfg == "HP" and self.mdl == "Fax") or \
  149.            ((self.devices[0].uri.startswith('dnssd:') or \
  150.              self.devices[0].uri.startswith('mdns:')) and \
  151.             self.devices[0].uri.endswith('/cups')):
  152.             info = self.devices[0].info
  153.         else:
  154.             info = "%s %s" % (self.mfg, self.mdl)
  155.         if len (self.sn) > 0:
  156.             info += " (%s)" % self.sn
  157.         elif self._network_host and len (self._network_host) > 0 and not \
  158.              ((self.devices[0].uri.startswith('dnssd:') or \
  159.                self.devices[0].uri.startswith('mdns:')) and \
  160.               self.devices[0].uri.endswith('/cups')):
  161.             info += " (%s)" % self._network_host
  162.         return info
  163.  
  164.     # User data
  165.     def set_data (self, key, value):
  166.         self._user_data[key] = value
  167.  
  168.     def get_data (self, key):
  169.         return self._user_data.get (key)
  170.  
  171.     def __str__ (self):
  172.         return "(description: %s)" % self.__repr__ ()
  173.  
  174.     def __repr__ (self):
  175.         return "<PhysicalDevice.PhysicalDevice (%s,%s,%s)>" % (self.mfg,
  176.                                                                self.mdl,
  177.                                                                self.sn)
  178.  
  179.     def __cmp__(self, other):
  180.         if other == None or type (other) != type (self):
  181.             return 1
  182.  
  183.         if (self._network_host != None or
  184.             other._network_host != None):
  185.             return cmp (self._network_host, other._network_host)
  186.  
  187.         if (other.mfg == '' and other.mdl == '') or \
  188.            (self.mfg == '' and self.mdl == ''):
  189.             # One or other is just a backend, not a real physical device.
  190.             if other.mfg == '' and other.mdl == '' and \
  191.                self.mfg == '' and self.mdl == '':
  192.                 return cmp (self.devices[0], other.devices[0])
  193.  
  194.             if other.mfg == '' and other.mdl == '':
  195.                 return -1
  196.             return 1
  197.  
  198.         if self.mfg == '' or self.mdl.lower ().startswith (self.mfg.lower ()):
  199.             our_make_and_model = self.mdl
  200.         else:
  201.             our_make_and_model = "%s %s" % (self.mfg, self.mdl)
  202.         (our_mfg, our_mdl) = \
  203.             cupshelpers.ppds.ppdMakeModelSplit (our_make_and_model)
  204.  
  205.         if other.mfg == '' or \
  206.                 other.mdl.lower ().startswith (other.mfg.lower ()):
  207.             other_make_and_model = other.mdl
  208.         else:
  209.             other_make_and_model = "%s %s" % (other.mfg, other.mdl)
  210.         (other_mfg, other_mdl) = \
  211.             cupshelpers.ppds.ppdMakeModelSplit (other_make_and_model)
  212.  
  213.         mfgcmp = cmp (our_mfg.lower (), other_mfg.lower ())
  214.         if mfgcmp != 0:
  215.             return mfgcmp
  216.         mdlcmp = cmp (our_mdl.lower (), other_mdl.lower ())
  217.         if mdlcmp != 0:
  218.             return mdlcmp
  219.         if self.sn == '' or other.sn == '':
  220.             return 0
  221.         return cmp (self.sn, other.sn)
  222.  
  223. if __name__ == '__main__':
  224.     import authconn
  225.     c = authconn.Connection ()
  226.     devices = cupshelpers.getDevices (c)
  227.  
  228.     physicaldevices = []
  229.     for device in devices.values ():
  230.         physicaldevice = PhysicalDevice (device)
  231.         try:
  232.             i = physicaldevices.index (physicaldevice)
  233.             physicaldevices[i].add_device (device)
  234.         except ValueError:
  235.             physicaldevices.append (physicaldevice)
  236.  
  237.     physicaldevices.sort ()
  238.     for physicaldevice in physicaldevices:
  239.         print physicaldevice.get_info ()
  240.         devices = physicaldevice.get_devices ()
  241.         for device in devices:
  242.             print " ", device
  243.